/**
 * 给定字符串S和T，其中T的长度最多只有5
 * 将S首先看作是空的，然后将T往里放，后放的会覆盖先放的
 * 问能否如此操作得到S
 * 
 * 首先注意到T只有5，如果T中有重复的字母，则有可能在某个位置会有多种选择
 * 可以考虑dfs搜索并剪枝，有类似AC代码
 * 
 * 个人觉得比较好的方法是DP，令Dij为S[0...i]是否恰好能放到T[0...j]
 * 则 如果 Si != Tj, 显然 Dij = 0
 * 如果 Si == Tj，则 
 * Dij = 1, if D[i-1][j-1] == 1, 此情况比较简单，既然前一个位置可以，则后一个位置也可以
 * Dij = 1, if D[i-1][M-1] == 1, 此情况说明前面完整匹配的，则该位置可以先放下，然后被前面覆盖即可
 * 注意 j == 0 是特殊的，有
 * Di0 = 1, if D[i-1][0....M-1] 任意为 1, 即前面只要能匹配上某个Tj, 则该位置直接从0开始放即可
 * 
 * 初始化写的比较繁琐，可以令 S = " " + S, T = " " + T
 * 则 D[0][0] = 1， 然后直接循环即可，更加简便
*/
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;

using llt = long long;
using vi = vector<int>;

int N, M;
string S, T;

bool proc(){
    if(N < M) return false;

    vector<vi> d(N, vi(M, 0));

    if(S[0] == T[0]) d[0][0] = 1;
    else return false;

    for(int i=1;i<M;++i){
        if(S[i] == T[0]){
            for(int j=0;j<i;++j)if(d[i-1][j]==1){d[i][0]=1;break;}
        }
        for(int j=1;j<=i;++j){
            if(S[i] == T[j]){
                if(d[i - 1][j - 1]) d[i][j] = 1;
            }
        }
    }

    for(int i=M;i<N;++i){
        if(S[i] == T[0]) {
            for(int j=0;j<M;++j)if(d[i-1][j]){d[i][0]=1;break;}
        }

        for(int j=1;j<M;++j){
            if(S[i] == T[j]){
                if(d[i - 1][j - 1]) d[i][j] = 1;
                if(d[i - 1][M - 1]) d[i][j] = 1;
            }
        }
    }

    return 1 == d[N - 1][M - 1];
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    cin >> N >> M >> S >> T;
    cout << (proc() ? "Yes" : "No") << endl;
    return 0;
}